import asyncio
import os
from abc import ABC, abstractmethod
from typing import AsyncGenerator, Any, Optional
from routes.local.streaming.stream_config import InputType, MediaType

from utils.logger import setup_logger
logger = setup_logger()

from utils.file_handler import read_file_stream, get_mime_type, get_file_type


class InputHandler(ABC):
    @abstractmethod
    async def process(self, input_data: Any) -> AsyncGenerator[Any, None]:
        pass

class VideoStreamInputHandler(InputHandler):
    async def process(self, input_data: Any) -> AsyncGenerator[Any, None]:
        logger.info("Processing video stream input")
        if isinstance(input_data, str) and os.path.isfile(input_data):
            # 如果是文件路径，使用文件流处理
            media_type = get_mime_type(input_data)
            async for chunk in read_file_stream(input_data, media_type=media_type):
                yield chunk
        else:
            # 直接处理流数据
            async for frame in input_data:
                # 确保视频数据是二进制格式
                if isinstance(frame, str):
                    try:
                        # 尝试将Base64编码的字符串转换为二进制
                        import base64
                        frame = base64.b64decode(frame)
                    except Exception:
                        # 如果不是Base64，则简单编码
                        frame = frame.encode('utf-8')
                yield frame

class AudioStreamInputHandler(InputHandler):
    async def process(self, input_data: Any) -> AsyncGenerator[Any, None]:
        logger.info("Processing audio stream input")
        if isinstance(input_data, str) and os.path.isfile(input_data):
            # 如果是文件路径，使用文件流处理
            media_type = get_mime_type(input_data)
            async for chunk in read_file_stream(input_data, media_type=media_type):
                yield chunk
        else:
            # 直接处理流数据
            async for chunk in input_data:
                # 确保音频数据是二进制格式
                if isinstance(chunk, str):
                    try:
                        # 尝试将Base64编码的字符串转换为二进制
                        import base64
                        chunk = base64.b64decode(chunk)
                    except Exception:
                        # 如果不是Base64，则简单编码
                        chunk = chunk.encode('utf-8')
                yield chunk

class TextStreamInputHandler(InputHandler):
    async def process(self, input_data: Any) -> AsyncGenerator[Any, None]:
        logger.info("Processing text stream input")
        if isinstance(input_data, str) and os.path.isfile(input_data):
            # 如果是文件路径，使用文件流处理
            async for chunk in read_file_stream(input_data, media_type='text/plain'):
                try:
                    # 尝试解码为文本
                    text = chunk.decode('utf-8')
                    yield text
                except UnicodeDecodeError:
                    # 如果解码失败，转换为字符串
                    yield str(chunk)
        else:
            # 直接处理流数据
            async for text in input_data:
                yield text

class ImageFileInputHandler(InputHandler):
    async def process(self, input_data: Any) -> AsyncGenerator[Any, None]:
        logger.info("Processing image file input")
        if isinstance(input_data, str) and os.path.isfile(input_data):
            # 处理图片文件
            media_type = get_mime_type(input_data)
            async for chunk in read_file_stream(input_data, media_type=media_type):
                yield chunk
        else:
            # 直接处理流数据
            async for chunk in input_data:
                yield chunk

class AudioFileInputHandler(InputHandler):
    async def process(self, input_data: Any) -> AsyncGenerator[Any, None]:
        logger.info("Processing audio file input")
        if isinstance(input_data, str) and os.path.isfile(input_data):
            # 处理音频文件
            media_type = get_mime_type(input_data)
            async for chunk in read_file_stream(input_data, media_type=media_type):
                yield chunk
        else:
            # 直接处理流数据
            async for chunk in input_data:
                yield chunk

class VideoFileInputHandler(InputHandler):
    async def process(self, input_data: Any) -> AsyncGenerator[Any, None]:
        logger.info("Processing video file input")
        if isinstance(input_data, str) and os.path.isfile(input_data):
            # 处理视频文件
            media_type = get_mime_type(input_data)
            async for chunk in read_file_stream(input_data, media_type=media_type):
                yield chunk
        else:
            # 直接处理流数据
            async for chunk in input_data:
                yield chunk

class TextFileInputHandler(InputHandler):
    async def process(self, input_data: Any) -> AsyncGenerator[Any, None]:
        logger.info("Processing text file input")
        if isinstance(input_data, str) and os.path.isfile(input_data):
            # 处理文本文件
            async for chunk in read_file_stream(input_data, media_type='text/plain'):
                try:
                    # 尝试解码为文本
                    text = chunk.decode('utf-8')
                    yield text
                except UnicodeDecodeError:
                    # 如果解码失败，转换为字符串
                    yield str(chunk)
        else:
            # 直接处理流数据
            async for text in input_data:
                yield text

class GenericFileInputHandler(InputHandler):
    async def process(self, input_data: Any) -> AsyncGenerator[Any, None]:
        logger.info("Processing generic file input")
        if isinstance(input_data, str) and os.path.isfile(input_data):
            # 处理通用文件
            media_type = get_mime_type(input_data)
            async for chunk in read_file_stream(input_data, media_type=media_type):
                yield chunk
        else:
            # 直接处理流数据
            async for chunk in input_data:
                yield chunk

def get_input_handler(input_type: InputType) -> InputHandler:
    handlers = {
        InputType.VIDEO_STREAM: VideoStreamInputHandler(),
        InputType.AUDIO_STREAM: AudioStreamInputHandler(),
        InputType.TEXT_STREAM: TextStreamInputHandler(),
        InputType.IMAGE_FILE: ImageFileInputHandler(),
        InputType.AUDIO_FILE: AudioFileInputHandler(),
        InputType.VIDEO_FILE: VideoFileInputHandler(),
        InputType.TEXT_FILE: TextFileInputHandler(),
        InputType.FILE: GenericFileInputHandler(),
    }
    return handlers.get(input_type, GenericFileInputHandler())